package com.dcy.znoa.service.publiz.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.dcy.znoa.common.exception.BusinessException;
import com.dcy.znoa.common.util.ZnoaConstant;
import com.dcy.znoa.common.util.pojo.JsonCommon;
import com.dcy.znoa.common.util.pojo.JsonForList;
import com.dcy.znoa.controller.publiz.model.SelectBaseModel;
import com.dcy.znoa.controller.publiz.model.company.SelectCompanyModel;
import com.dcy.znoa.controller.publiz.model.company.SelectNotInByEsIdModel;
import com.dcy.znoa.dao.publiz.CompanyDao;
import com.dcy.znoa.dao.publiz.DepartmentDao;
import com.dcy.znoa.dao.publiz.PlaceDao;
import com.dcy.znoa.dao.sys.RoleAuthDao;
import com.dcy.znoa.dao.sys.RoleDao;
import com.dcy.znoa.dao.sys.UrlListDao;
import com.dcy.znoa.domain.Oper;
import com.dcy.znoa.domain.publiz.Company;
import com.dcy.znoa.domain.publiz.Department;
import com.dcy.znoa.domain.publiz.Place;
import com.dcy.znoa.domain.sys.OperRole;
import com.dcy.znoa.domain.sys.Role;
import com.dcy.znoa.domain.sys.UrlList;
import com.dcy.znoa.service.publiz.CompanyService;
import com.dcy.znoa.service.publiz.DepartmentService;
import com.dcy.znoa.service.publiz.PlaceService;
import com.dcy.znoa.service.software.OperService;
import com.dcy.znoa.service.sys.OperRoleService;
import com.google.common.base.Strings;

import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.List;

import static com.dcy.znoa.common.enums.OperTypeCode.COPER;
import static com.dcy.znoa.common.enums.OperTypeCode.PLACEMGR;
import static com.dcy.znoa.domain.Oper.SYS_OPER_ID;
import static com.dcy.znoa.domain.publiz.Department.TO_AUDIT;
import static java.util.stream.Collectors.toList;

@Service
public class CompanyServiceImpl implements CompanyService {

    //    @Autowired
//    private HttpSession session;
    @Autowired
    CompanyDao companyDao;
    @Autowired
    DepartmentDao departmentDao;
    @Autowired
    OperService operService;
    @Autowired
    DepartmentService departmentService;
    @Autowired
    OperRoleService operRoleService;
    @Autowired
    RoleDao roleDao;
    @Autowired
    UrlListDao urlListDao;
    @Autowired
    RoleAuthDao roleAuthDao;
    @Autowired
    PlaceService placeService;
    @Autowired
    PlaceDao placeDao;


    //pengyu modify  20180501 此接口用前端传参去查询接口，后端不用用户类型去区分
    @Override
    public JsonForList selectList(Oper oper, SelectCompanyModel model) throws InvocationTargetException, IllegalAccessException {
        Integer total;
        Integer operType = oper.getOperType();
        if (operType == null) {
            return new JsonForList(null, "此用户没有对应的用户类型");
        }
        List<Company> list;
        EntityWrapper<Company> ew = new EntityWrapper<>();
        ew.like("comp_name", model.getCompName())
                .like("address", model.getAddress())
                .like("contact", model.getContact())
                .like("contact_man", model.getContactMan());
        if (!Strings.isNullOrEmpty(model.getDistrictCode())) {
            ew.eq("district_code", model.getDistrictCode());
        }
        if (!Strings.isNullOrEmpty(model.getTyshxybm())) {
            ew.eq("tyshxybm", model.getTyshxybm());
        }
        if (model.getValidFlag() != null) {
            ew.eq("valid_flag", model.getValidFlag());
        }
        if (model.getEsId() != null) {
            ew.eq("es_id", model.getEsId());
        }
        if (model.getCompType() != null) {
            ew.eq("comp_type", model.getCompType());
        }
//                ew.eq("valid_flag",1);

        //1 分页方法1，需要model继承 SelectBaseModel
//                if(model.getPageNum()>0 && model.getPageSize() >0){
//                    Page page  =new Page(model.getPageNum(),model.getPageSize());
//                    SqlHelper.fillWrapper(page,ew);
//                    total = companyDao.selectCount(ew);
//                }
//                SelectBaseModel.PageFill(model,ew);//加入分页参数
        Page page = new Page(model.getPageNum(), model.getPageSize());
        list = companyDao.selectPage(page, ew);

//                list = companyDao.selectListMapper(ew);
        //2 分页方法2 ，需要model里面包含 RowBounds 类，查询调用分页方法,但是 RowBounds里面的参数是MySQL 对应的，有点反人类，第一页要从0开始。
//                list = companyDao.selectPage(model.getRowBounds(),ew);
//        if (list.isEmpty()) {
//            return new JsonForList(JsonCommon.NOT_FOUND_CODE);
//        }
        return new JsonForList(list, page.getTotal());
//        switch (operType) {
//            case ZnoaConstant.PLATFORM_MANAGER:
//                EntityWrapper<Company> ew = new EntityWrapper<>();
//                ew.like("comp_name", model.getCompName())
//                        .like("address", model.getAddress())
//                        .like("contact", model.getContact())
//                        .like("contact_man", model.getContactMan());
//                if (!Strings.isNullOrEmpty(model.getDistrictCode())) {
//                    ew.eq("district_code", model.getDistrictCode());
//                }
//                if (!Strings.isNullOrEmpty(model.getTyshxybm())) {
//                    ew.eq("tyshxybm", model.getTyshxybm());
//                }
//                if (model.getValidFlag() != null) {
//                    ew.eq("valid_flag", model.getValidFlag());
//                }
//                if (model.getEsId()!=null) {
//                    ew.eq("es_id", model.getEsId());
//                }
//                if (model.getCompType()!=null) {
//                    ew.eq("comp_type", model.getCompType());
//                }
////                ew.eq("valid_flag",1);
//
//                //1 分页方法1，需要model继承 SelectBaseModel
////                if(model.getPageNum()>0 && model.getPageSize() >0){
////                    Page page  =new Page(model.getPageNum(),model.getPageSize());
////                    SqlHelper.fillWrapper(page,ew);
////                    total = companyDao.selectCount(ew);
////                }
////                SelectBaseModel.PageFill(model,ew);//加入分页参数
//                Page page = new Page(model.getPageNum(), model.getPageSize());
//                list = companyDao.selectPage(page, ew);
//
////                list = companyDao.selectListMapper(ew);
//                //2 分页方法2 ，需要model里面包含 RowBounds 类，查询调用分页方法,但是 RowBounds里面的参数是MySQL 对应的，有点反人类，第一页要从0开始。
////                list = companyDao.selectPage(model.getRowBounds(),ew);
//                if (list.isEmpty()) {
//                    return new JsonForList(JsonCommon.NOT_FOUND_CODE);
//                }
//                return new JsonForList(list, page.getTotal());
//            case ZnoaConstant.COMPANY_MANAGER:
//                EntityWrapper<Company> ewCm = new EntityWrapper<>();
//                Long companyId = oper.getCompId();
//                if (companyId == null || companyId <= 0) {
//                    return new JsonForList(null, "此企业用户管理员没有对应的企业");
//                }
//                ewCm.eq("comp_id", companyId);
//                total = SelectBaseModel.PageFill(model, ewCm, companyDao);//加入分页参数
//                list = companyDao.selectList(ewCm);
//                if (list.isEmpty()) {
//                    return new JsonForList(JsonCommon.NOT_FOUND_CODE);
//                }
//                return new JsonForList(list, total);
//            case ZnoaConstant.COMPANY_USER:
//                return new JsonForList(null, "企业用户无权访问此接口");
//            default:
//                return new JsonForList(null, "此用户的用户类型错误");
//        }
    }

    @Transactional
    @Override
    public JsonCommon insert(Company var1) throws BusinessException {
        Company company = companyDao.selectOne(new Company(var1.getCompName()));
        if (company != null) {
            throw new BusinessException("804", "已经存在同名的公司！");
        }
        Integer result = companyDao.insert(var1);
        if (result == null || result <= 0) {
            return new JsonCommon(JsonCommon.INSERT_ERROR_CODE);
        }
        //新增一个公司下的根结点部门
        Department department = new Department(var1.getCompName(), 1, 1, var1.getCompId(), null, var1.getCreateOperId(), new Date(), 1);
        Integer result1 = departmentDao.insert(department);
        if (result1 == null || result1 <= 0) {
            return new JsonCommon(JsonCommon.INSERT_ERROR_CODE);
        }
        return new JsonCommon(var1, JsonCommon.SUCCESS_CODE, JsonCommon.SUCCESS_MSG);
    }

    @Override
    public JsonCommon updateById(Company var1) {
        //如果修改了公司名称
        Long compId = var1.getCompId();
        Company company = companyDao.selectById(compId);
        String compName = var1.getCompName();

        if (compName != null && !compName.equals(company.getCompName())) {
            //修改公司顶层部门名称
            Department depQuery = new Department();
            depQuery.setCompId(compId);
            depQuery.setDepLevel(1);
            Department department = departmentDao.selectOne(depQuery);
            department.setDepName(compName);
            departmentDao.updateById(department);
            departmentService.updateRedis(compId);
        }
        //如果把公司类型从公司改成物业，则要判断此公司有没有关联过物业：如果已关联，则不允许修改公司类型
//        if(Integer.valueOf(1).equals(company.getCompType()) && Integer.valueOf(1).equals(var1.getCompType()) && company.getEsId()!=null){
//            return new JsonCommon(JsonCommon.UPDATE_ERROR_CODE,"如果已关联物业的公司，则不允许修改公司类型成物业");
//        }

        Integer result = companyDao.updateById(var1);
        if (result == null || result <= 0) {
            return new JsonCommon(JsonCommon.UPDATE_ERROR_CODE);
        }

        return new JsonCommon(JsonCommon.SUCCESS_CODE, JsonCommon.SUCCESS_MSG);
    }

    @Override
    public JsonCommon selectById(Integer id) throws BusinessException {
        if (id == null) {
            throw new BusinessException("404", "企业id不能为空！");
        }
        return new JsonCommon(companyDao.selectById(id));
    }

    @Transactional
    @Override
    public JsonCommon insertCompAndOper(Company var1, Oper op) throws BusinessException {
        Company company = companyDao.selectOne(new Company(var1.getCompName()));
        if (company != null) {
            throw new BusinessException("804", "已经存在同名的公司！");
        }
        Integer result = companyDao.insert(var1);
        if (result == null || result <= 0) {
            return new JsonCommon(JsonCommon.INSERT_ERROR_CODE, "新增公司失败");
        }
        //新增一个场所
//        没法查询公司对应的园区对应的场所ID，因为APP操作的时候目前没法选园区ID  park_id ，所以默认为1 parkid对应的placeId为1 ，在初始化脚本中加入
        //公司是2级，园区是1级
        Place place = new Place(var1.getCompName(), 2, 2, 1L, var1.getCompId(), op.getOperId());
        Integer result0d5 = placeService.insert(place);
        if (result0d5 == null || result0d5 <= 0) {
            return new JsonCommon(JsonCommon.INSERT_ERROR_CODE, "新增场所失败");
        }
        //新增一个公司同名的顶级部门(根结点部门)
        Department department = new Department(var1.getCompName(), 1, 1, var1.getCompId(), null, var1.getCreateOperId(), new Date(), 1);
//      Department department = new Department("公司",1,1,var1.getCompId(),var1.getCreateOperId(),new Date(),1);
        Integer result1 = departmentDao.insert(department);
        if (result1 == null || result1 <= 0) {
            return new JsonCommon(JsonCommon.INSERT_ERROR_CODE, "新增顶层部门失败");
        }
        //在根节点下放置一个TO_AUDIT的部门
        Department toAuditDep = new Department(TO_AUDIT, 2, 1, var1.getCompId(), department.getDepId(), var1.getCreateOperId(), new Date(), 1);
        Integer result2 = departmentDao.insert(toAuditDep);
        if (result2 == null || result2 <= 0) {
            return new JsonCommon(JsonCommon.INSERT_ERROR_CODE, "新增待审核部门失败");
        }
//      company = (Company) jc.getData();
        Long compId = var1.getCompId();
        op.setCompId(compId);
        op.setDepId(department.getDepId());
        op.setIsAudit(1);//默认审核成功
        //如果前端不传企业类型的话，就默认是企业，用户也就是企业管理员
        Integer compType = var1.getCompType();//企业类型：1 企业 2 物业
        op.setOperType(COPER.getCode());
        if (compType != null) {
            switch (compType) {
                case 1:
                    op.setOperType(COPER.getCode());
                    break;
                case 2:
                    op.setOperType(PLACEMGR.getCode());
                    break;
                default:
                    return new JsonCommon(JsonCommon.INSERT_ERROR_CODE, "企业类型只能是1或2");
            }
        }
        Oper oper = operService.save(op);
        if (oper != null) {
//            return  new JsonCommon(oper);
            if (null != oper.getOperId()) {
                OperRole operRole = new OperRole();
                operRole.setOperId(oper.getOperId());
                operRole.setValidFlag(1);
                operRole.setCreateOperId(oper.getOperId());
                //先查询有没有这个企业下的管理员，如果没有就新加一个，然后赋值给这个operRole
                Role role = roleDao.selectOne(new Role(compId, 1));//1 为 是管理员 ，0 为不是;
                List<UrlList> urlListList = null;
                List<Long> urlIdList = null;
                switch (compType) {
                    case 1:
                        if (role == null) {
//                        public Role(String roleName, String describe, Long compId, String compName, Long createOperId, Date createTime, Integer validFlag, Integer isManager) {
                            role = new Role("企业管理员", "勿删", compId, "", SYS_OPER_ID, new Date(), 1, 1);
                            Integer ResultAdd = roleDao.insert(role);
                            if (ResultAdd <= 0) {
                                return new JsonCommon(JsonCommon.INSERT_ERROR_CODE, "新增默认管理员角色失败");
                            }
                        }
//                operRole.setRoleId(812L);    //812  企业管理员默认角色
                        operRole.setRoleId(role.getRoleId());
                        operRoleService.insert(operRole);
                        //角色 和 权限 绑定
                        urlListList = urlListDao.selectList(new EntityWrapper<UrlList>().ne("belong", 1));
                        urlIdList = urlListList.stream().map(UrlList::getUrlId).collect(toList());
                        roleAuthDao.addBatch(role.getRoleId(), urlIdList);
                        break;
                    case 2:
                        if (role == null) {
//                        public Role(String roleName, String describe, Long compId, String compName, Long createOperId, Date createTime, Integer validFlag, Integer isManager) {
                            role = new Role("物业管理员", "勿删", compId, "", SYS_OPER_ID, new Date(), 1, 1);
                            Integer ResultAdd = roleDao.insert(role);
                            if (ResultAdd <= 0) {
                                return new JsonCommon(JsonCommon.INSERT_ERROR_CODE, "新增默认管理员角色失败");
                            }
                        }
//                operRole.setRoleId(812L);    //812  企业管理员默认角色
                        operRole.setRoleId(role.getRoleId());
                        operRoleService.insert(operRole);
                        //角色 和 权限 绑定
                        urlListList = urlListDao.selectList(new EntityWrapper<UrlList>().like("url_name","物业"));
                        urlIdList = urlListList.stream().map(UrlList::getUrlId).collect(toList());
                        roleAuthDao.addBatch(role.getRoleId(), urlIdList);
                        break;
                }

            }

            departmentService.updateRedis(compId);
            return new JsonCommon(var1);
        }
        return new JsonCommon("804", "新增用户失败！");
    }

    @Override
    public boolean connectToEstate(Long esId, Long operId, List<String> listIds) {
        boolean result = false;
        Integer resultInt = companyDao.connectToEstate(esId, operId, listIds);
        if (resultInt != null && resultInt > 0) {
            result = true;
        }
        return result;
    }

    @Override
    public boolean setValidFlag(Integer validFlag, Long operId, List<String> listIds) {
        boolean result = false;
        Integer resultInt = companyDao.setValidFlag(validFlag, operId, listIds);
        if (resultInt != null && resultInt > 0) {
            result = true;
        }
        return result;
    }

    //esId 这个参数暂时不用，按原型。
    @Override
    public List selectList(SelectNotInByEsIdModel model) {
        EntityWrapper<Company> ew = new EntityWrapper<>();
        ew.setEntity(new Company());
        Long esId = model.getEsId();
        String compName = model.getCompName();
        if (esId != null) {
            StringBuilder sb = new StringBuilder("where 1 = 1 ");
//          sb.append("where es_id != " + esId);
            if (StringUtils.isNotBlank(compName)) {
                sb.append(" and comp_name like '%" + compName + "%'");
//                ew.like("comp_name",compName) ;
            }
            sb.append(" and comp_type = 1 and es_id is null order by create_time desc ");
            ew.last(sb.toString());
//            ew.last(" where os_type = " + osType + " and  valid_flag = 1 order by version desc  limit 1");
        }
        Page page = new Page(model.getPageNum(), model.getPageSize());
        return companyDao.selectPage(page, ew);
    }

    @Override
    public boolean untieToEstate(Long operId, List<String> listIds) {
        boolean result = false;
        Integer resultInt = companyDao.untieToEstate(operId, listIds);
        if (resultInt != null && resultInt > 0) {
            result = true;
        }
        return result;
    }


}
